package com.threeti.mecool.core.application.basicdata;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import com.threeti.mecool.core.domain.model.basicdata.AdminDivision;
import com.threeti.mecool.core.domain.model.basicdata.AdminDivisionLevelDeep;
import com.threeti.mecool.core.domain.model.basicdata.Brand;
import com.threeti.mecool.core.domain.model.basicdata.BrandCategory;
import com.threeti.mecool.core.domain.model.basicdata.Customer;
import com.threeti.mecool.core.domain.model.basicdata.Product;
import com.threeti.mecool.core.domain.model.basicdata.biz.Channel;
import com.threeti.mecool.core.domain.model.basicdata.biz.ChannelCategory;
import com.threeti.mecool.core.domain.model.basicdata.biz.ChannelSysCategory;
import com.threeti.mecool.legacy.domain.model.basicdata.CustomerLegacy;
import com.threeti.mecool.legacy.domain.model.basicdata.MDCustomer;

/**
 * 基础数据服务
 *
 * @author Jay Meng
 */
public interface BasicDataService {

    /**
     * 预处理特定通路(终端、门店)<p>
     * <p/>
     * 1.本方法对于Channel的类别ChannelCategory，只抓取了其Code而未抓取其Name <br/>
     * 2.本方法具有ETL功能(主要指ETL出能够开箱即用的地域数据)，面对凌乱的可能存在错误的或者说不符合业务需求需要改造的地域基础数据，经过纠错或校正，自动流出干净的符合业务需求的数据<br/>
     * 3.很大程度上，本方法抓取出正确数据的目的是为了更准确、精确地服务于报表或搜索统计<br/>
     * 4.本方法依赖于底层遗留数据库表MD_ADMIN_DIV关于地理行政地域的数据存储和地域编码方式，假设该方式不会改变，如果改变，那么本方法可能会出错
     *
     * @param channelCode 通路的唯一编号，来源于遗留系统
     */
    Channel preProcessChannelBy(String channelCode);

    /**
     * 分页取得 通路(终端、门店) 集合
     */
    @Deprecated
    Page<Channel> findChannels(Pageable pageable);

    /**
     * 取得所有 通路类别(整树抓取)
     */
    List<ChannelCategory> findAllChannelCategories();

    /**
     * 取得所有 通路系统类型
     */
    List<ChannelSysCategory> findAllChannelSysCategories();

    /**
     * 取得所有 客户 集合
     */
    List<Customer> findAllCustomers();

    /**
     * 取得 特定客户的品类(品牌种类)集合 (已按品类Code升序排序)
     */
    Set<BrandCategory> findBrandCategoriesByCustomer(String customerCode);

    /**
     * (按品类)取得 特定客户的品牌集合
     */
    List<Brand> findBrandsByCustomerAndBrandCateogry(String customerCode, String brandCategoryCode);

    /**
     * (按品类和品牌)取得 产品明细集合
     */
    List<Product> findProductsByBrandCategoryAndBrand(String brandCategoryCode, String brandCode);

    /**
     * 按 行政区划深度 获取 国家行政区划树 TODO jay:hide
     *
     * @param levelDeep 行政区划深度，即树的深度，谨慎使用， levelDeep > PROVINCE时，将引起整树抓取性能损耗严重
     */
    List<AdminDivision> findAdminDivisionsByLevelDeep(AdminDivisionLevelDeep levelDeep);

    /**
     * 按 特定上级行政区划和指定行政区划等级 获取下级地区
     *
     * @param parentProvinceAdName 上级行政区划PROVINCE级名字  比如，江苏省
     * @param parentAdCode         上级行政区划名字编码  比如，江苏省AdCode
     * @see com.threeti.mecool.core.domain.model.basicdata.AdminDivisionLevelDeep
     */
    List<AdminDivision> findAdminDivisionsByParentProvinceAdNameAndLevelDeep(String parentProvinceAdName, String parentAdCode, AdminDivisionLevelDeep levelDeep);

    /**
     * 按 特定上级行政区划(上级行政区划等级深度必须 >= AdminDivisionLevelDeep.PROVINCE级) 获取下级地区
     *
     * @param parentCityAdName 上级行政区划CITY级名字  比如，南京市(隶属于江苏省) 或 南京市市辖区(隶属于南京市)
     * @param parentAdCode     上级行政区划名字编码  比如，南京市AdCode 或 南京市市辖区AdCode(隶属于南京市)
     * @see com.threeti.mecool.core.domain.model.basicdata.AdminDivisionLevelDeep
     */
    List<AdminDivision> findAdminDivisionsByParentCityAdNameAndAdCode(String parentCityAdName, String parentAdCode);

    /**
     * 取得完整的 国家行政区划(地理位置)信息(整树抓取)，性能损耗巨大，仅供测试用
     */
    @Deprecated
    List<AdminDivision> findAllAdminDivision();

    /**
     * 取得 特定客户的所有产品(项目采集项的来源)集合，仅供测试用
     */
    @Deprecated
    Set<Product> findAllProductsByCustomerCode(String customerCode);

    MDCustomer findMDCustomerByCustomerLegacy(CustomerLegacy customerLegacy);
    

    /**
	 * 树形缩进结果
	 * @author Yuqi Chou
	 * @return
	 * @version Oct 26, 2012  3:44:39 PM
	 */
	List<Map<String, Object>> findAllPosKindListByTreeFormat();
}
